{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "initial_id",
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2024-05-16T01:48:08.347950Z",
     "start_time": "2024-05-16T01:48:08.322004400Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "tensor([0., 1., 2., 3.])"
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import torch\n",
    "\n",
    "x = torch.arange(4.0)\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "source": [
    "相求导数  y = 2 * x转置 x"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "1807f6f3aa011180"
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "outputs": [],
   "source": [
    "x.requires_grad_(True)  # 仅浮点数类型的可以用梯度 \n",
    "x.grad"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-16T01:48:08.349950500Z",
     "start_time": "2024-05-16T01:48:08.334690400Z"
    }
   },
   "id": "8d9f956475cef4e8"
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "outputs": [
    {
     "data": {
      "text/plain": "tensor(28., grad_fn=<MulBackward0>)"
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y = 2 * torch.dot(x, x)\n",
    "y"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-16T01:48:08.409632200Z",
     "start_time": "2024-05-16T01:48:08.336687400Z"
    }
   },
   "id": "acc94de31b8eb2fe"
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "outputs": [
    {
     "data": {
      "text/plain": "tensor([ 0.,  4.,  8., 12.])"
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y.backward()\n",
    "x.grad"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-16T01:48:08.417633800Z",
     "start_time": "2024-05-16T01:48:08.346949300Z"
    }
   },
   "id": "32dc30071758ab69"
  },
  {
   "cell_type": "markdown",
   "source": [],
   "metadata": {
    "collapsed": false
   },
   "id": "5505eb7c2779a08d"
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "outputs": [
    {
     "data": {
      "text/plain": "tensor([True, True, True, True])"
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x.grad == 4 * x"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-16T01:48:08.418634100Z",
     "start_time": "2024-05-16T01:48:08.356713900Z"
    }
   },
   "id": "537113879555f613"
  },
  {
   "cell_type": "markdown",
   "source": [
    "求和 相当于 y = x1 + x2 +++ , 对x (x1,x2,x3...) 求导后变为 1 1 1 1"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "a2bb2c600055364"
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "outputs": [
    {
     "data": {
      "text/plain": "tensor([ 1.,  5.,  9., 13.])"
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x.grad.zero_() # 默认梯度是会增加的\n",
    "y = x.sum() \n",
    "y.backward()\n",
    "x.grad"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-16T01:48:08.418634100Z",
     "start_time": "2024-05-16T01:48:08.364692800Z"
    }
   },
   "id": "f825f19592625245"
  },
  {
   "cell_type": "markdown",
   "source": [
    "y = x1^2 + x2^2 +++ , 所以求导之后 变成 2 * x1, 2 * x2 ..."
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "2cbdd4e493641f76"
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([0., 1., 4., 9.], grad_fn=<MulBackward0>)\n"
     ]
    },
    {
     "data": {
      "text/plain": "tensor([0., 2., 4., 6.])"
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x.grad.zero_()\n",
    "y = x * x\n",
    "print(y)\n",
    "y.sum().backward()\n",
    "x.grad"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-16T01:52:03.964683700Z",
     "start_time": "2024-05-16T01:52:03.952582800Z"
    }
   },
   "id": "140709e31daf0cfa"
  },
  {
   "cell_type": "markdown",
   "source": [
    "将某些计算移动到记录的计算图之外 detach"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "928b1b420ae401de"
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "outputs": [
    {
     "data": {
      "text/plain": "tensor([True, True, True, True])"
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x.grad.zero_()\n",
    "y = x *x\n",
    "u = y.detach()  # detach 后 u 此时不是x的函数\n",
    "z = u * x\n",
    "\n",
    "z.sum().backward()\n",
    "x.grad == u"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-16T01:55:47.659233200Z",
     "start_time": "2024-05-16T01:55:47.644504400Z"
    }
   },
   "id": "1b8b70e2a8cd823a"
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor(102400.) tensor(102399.9922, grad_fn=<DivBackward0>)\n"
     ]
    },
    {
     "data": {
      "text/plain": "tensor(False)"
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def f(a):\n",
    "    b = a * 2\n",
    "    while b.norm() < 1000: # norm可以理解为 2 范数\n",
    "        b = b * 2\n",
    "    if b.sum() > 0:\n",
    "        c  = b\n",
    "    else:\n",
    "        c = 100 * b\n",
    "    return c\n",
    "\n",
    "a = torch.randn(size=(), requires_grad=True)\n",
    "d = f(a)\n",
    "d.backward()\n",
    "print(a.grad, d / a)\n",
    "a.grad == d / a"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-16T02:17:55.369280900Z",
     "start_time": "2024-05-16T02:17:55.365895100Z"
    }
   },
   "id": "2e34e004b16527d"
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-16T02:02:39.510481100Z",
     "start_time": "2024-05-16T02:02:39.504482600Z"
    }
   },
   "id": "ae44141e12549ef7"
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-16T02:02:40.874620500Z",
     "start_time": "2024-05-16T02:02:40.869622500Z"
    }
   },
   "id": "f9001690023b0735"
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false
   },
   "id": "83c3da79db6c9df4"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
